' *** Documentation
' 
' VB Script Class: VbDataset
' 
' last updated: Jul 2007
' author: klenwell@gmail.com
' 
' DESCRIPTION
'  a class for organizing data in sets 
' 
' NOTES
' 
' ____________________________________________________________________________*/

' *** DECLARATIONS
Option Explicit


' *** CLASS
Class vbDataset

	' Private Class Variables
	Private m_Index()
	Private m_Dataset()
	Private m_IndexOffset
	Private m_IndexPointer
	Private m_DatasetOffset
	Private m_DrilledDown

	' Constructor
	Private Sub Class_Initialize()
		'MsgBox("initializing class")
		m_IndexOffset = -1
		m_DatasetOffset = 0
		m_IndexPointer = 0
	End Sub
	
	' Destructor
	Private Sub Class_Terminate()
		'MsgBox("terminating class")
	End Sub
	
	' Method: advance index pointer
	Public Function NextSet()
	
		If ( m_IndexPointer <= m_IndexOffset  ) Then
			NextSet = True
		Else
			m_IndexPointer = 0
			NextSet = False
		End If
		
	End Function
	
	' Method: advance index pointer
	Public Function Advance()
		m_IndexPointer = m_IndexPointer + 1
		Advance = True
	End Function
	
	' Method: get (current) index -> for use with NextSet/Advance
	Public Property Get Index()
		Index = m_Index(m_IndexPointer)
	End Property
	
	' Method: return current dataset as array -> for use with NextSet/Advance
	Public Property Get Dataset()

		' stick dataset in an array
		Dim n1, n2, tmpArray()
		ReDim tmpArray(m_DatasetOffset)
		For n1 = 0 to m_DatasetOffset
			If ( IsObject(m_Dataset(m_IndexPointer, n1)) ) Then
				Set tmpArray(n1) = m_Dataset(m_IndexPointer, n1)
			Else
				tmpArray(n1) = m_Dataset(m_IndexPointer, n1)
			End If
		Next
		
		Dataset = tmpArray
	End Property
	
	' Method: reset index point
	Public Function Reset()
		m_IndexPointer = 0
		Reset = True
	End Function
	
	
	' Method: add dataset
	Public Sub addDataset(sId, vData)
		If Not inIndex(sId) Then
			'MsgBox("adding new dataset named " & sId)
			Call pushNewDataset(sId, vData)
		Else
			'MsgBox("adding to existing dataset named " & sId)
			Call pushExistingDataset(sId, vData)
		End If
	End Sub
	
	' Method: push new dataset
	Private Sub pushNewDataset(sId, vData)
		
		' Push index array
		Call pushIndex(sId)
		
		'MsgBox("pushNewDataset - new m_IndexOffset: " & m_IndexOffset)		
		
		' Add data to 0 element of new dataset
		If Not isObject(vData) Then
			'MsgBox("adding non-object: " & typename(vData) & " / " &  sId)
			m_Dataset(m_IndexOffset, 0) = vData
		Else
			'MsgBox("adding object: " & typename(vData) & " / " &  sId)
			Set m_Dataset(m_IndexOffset, 0) = vData
		End If		
		
	End Sub
	
	' Method: push existing dataset
	Private Sub pushExistingDataset(sId, vData)
		Dim i, iIdOffset
		
		' Find index offset value for this dataset id
		For i = 0 to m_IndexOffset
			If ( sId = m_Index(i) ) Then
				iIdOffset = i
				Exit For
			End If
		Next
		'MsgBox("iIdOffset = " & iIdOffset)		
		
		' Do we need to push the dataset offset?
		Dim doPushDatasetOffset
		doPushDatasetOffset = True
		
		On Error Resume Next
		Dim iSetNext, sType
		iSetOff = -1
		For i = 0 to m_DatasetOffset
			sType = TypeName(m_Dataset(iIdOffset,i))
			'MsgBox("sType " & iIdOffset & "," & i & " : " & sType)
			If ( sType = "Empty" ) Then
				doPushDatasetOffset = False
				iSetNext = i
				Exit For
			End If
		Next
		'MsgBox("doPushDatasetOffset = " & doPushDatasetOffset)
		
		' If next offset in this dataset > m_DatasetOffset, we need to increase offset and redim array 
		If ( doPushDatasetOffset ) Then
			m_DatasetOffset = m_DatasetOffset + 1
			iSetNext = m_DatasetOffset
			'MsgBox("pushExistingDataset - new m_DatasetOffset: " & m_DatasetOffset)
			ReDim Preserve m_Dataset(m_IndexOffset, m_DatasetOffset)
		End If		
		
		' Add data to new dataset offset element of existing dataset
		If Not isObject(vData) Then
			m_Dataset(iIdOffset, iSetNext) = vData
		Else
			Set m_Dataset(iIdOffset, iSetNext) = vData
		End If	

	End Sub
	
	' Method: push index
	Private Function pushIndex(sId)
		
		' Increase index array
		m_IndexOffset = m_IndexOffset + 1
		ReDim Preserve m_Index(m_IndexOffset)
		
		' Redim dataset array
		Call redimDataset
		
		' Assign index array
		m_Index(m_IndexOffset) = sId

	End Function
	
	' Method: redim 2d array
	Private Sub redimDataset()
		On Error Resume Next
		
		Dim i, j, i1
		Dim tmpArray()
		i1 = m_IndexOffset - 1

		'MsgBox("redimDataset: " & m_IndexOffset & "," & m_DatasetOffset)
		Redim tmpArray(m_IndexOffset, m_DatasetOffset)
		For i = 0 to i1
			For j = 0 to m_DatasetOffset
				'MsgBox("m_Dataset " & i & "," & j & " : " & m_Dataset(i, j))
				'tmpArray(i, j) = m_Dataset(i, j)
				If Not isObject(m_Dataset(i, j)) Then
					tmpArray(i, j) = m_Dataset(i, j)
				Else
					Set tmpArray(i, j) = m_Dataset(i, j)
				End If	
			Next
		Next

		Redim m_Dataset(m_IndexOffset, m_DatasetOffset)
		For i = 0 to m_IndexOffset
			For j = 0 to m_DatasetOffset
				'm_Dataset(i, j) = tmpArray(i, j)
				If Not isObject(tmpArray(i, j)) Then
					m_Dataset(i, j) = tmpArray(i, j)
				Else
					Set m_Dataset(i, j) = tmpArray(i, j)
				End If	
				If Err.number <> 0 Then
					m_Dataset(i, j) = Null
					Err.Clear()
				End If				
			Next
		Next

	End Sub
	
	' Method: in index
	Private Function inIndex(sId)
		If Not isArray(m_Index) Then
			inIndex = False
			Exit Function
		Else
			Dim i
			For Each i in m_Index
				If i = sId Then
					inIndex = True
					Exit Function
				End If
			Next
		End If
		inIndex = False
	End Function
	
	' Method: dump
	Public Function Dump()
	
		Dump = printDataset()
	
	End Function
	
	' Method: print dataset
	Public Function printDataset()
	
		printDataset = "Dataset Object Dump: " & vbNewLine
		
		Dim i
		
		' Find index offset value for this dataset id
		For i = 0 to m_IndexOffset
			Dim sKey, sDataset
			sKey = m_Index(i)
			printDataset = printDataset & vbTab & "Index Key: " & sKey & vbNewLine
			
			Dim d
			For d = 0 to m_DatasetOffset
				printDataset = printDataset & vbTab & vbTab & printR(m_Dataset(i, d), "Dataset")	
			Next
		Next
		
	End Function
	
	' Method: printDatasetType()
	Public Function printDatasetType()
		printDatasetType = "Dataset Type Dump: " & vbNewLine
		Dim i, d, sType
		For i = 0 to m_IndexOffset
			For d = 0 to m_DatasetOffset
				sType = TypeName(m_Dataset(i, d))
				printDatasetType = printDatasetType & vbTab & m_Index(i) & ": " & sType & vbNewLine
			Next
		Next
	End Function
	
	' Method: print r
	Public Function printR(ByVal vVar, sName)
	
		'On Error Resume Next
		
		' Return
		printR = ""
		
		' Name
		If isEmpty(sName) Then: sName = "Variable": End If
		If ( m_DrilledDown = 0 ) Then
			'printR = "vbPrintR :: " & sName & vbNewLine & vbNewLine
		End If
		
		' Var Type
		Dim sVarType
		sVarType = TypeName(vVar)
		
		' Debug
		'MsgBox("Drilled Down : " & iArrayDrillDown)
		
		' Add Tabs
		Dim sTabPrt, iTabs
		sTabPrt = ""
		iTabs = m_DrilledDown
		Do While iTabs > 0
			sTabPrt = sTabPrt & vbTab
			iTabs = iTabs - 1
		Loop
		printR = printR & sTabPrt
		
		m_DrilledDown = m_DrilledDown + 1
		
		' Is Array
		If IsArray(vVar) Then
			Dim vEl
			printR = printR & "Array: " & vbNewLine
			For Each vEl In vVar
				printR = printR & printR(vEl, Null)
			Next
			
		' Is Dictionary
		ElseIf IsObject(vVar) And sVarType = "Dictionary" Then
			Dim vKey
			printR = printR & "Dictionary Object: " & vbNewLine
			For Each vKey In vVar
				printR = printR & sTabPrt & vbTab & vKey & " : " & vVar.Item(vKey) & vbNewLine
			Next
			
		' Is Dataset
		ElseIf IsObject(vVar) And sVarType = "vbDataset" Then 
			'MsgBox("print vbDataset")
			printR = printR & sTabPrt & vVar.Dump() 
		
		' Other Object
		ElseIf IsObject(vVar) Then
			printR = printR & "Object : " & sVarType & vbNewLine
		
		' Other Var
		Else
			printR = printR & sVarType & " : " & vVar & vbNewLine
		End If
		
		m_DrilledDown = m_DrilledDown - 1

	End Function

End Class



